/*!
 * \file test_module_helper.cpp
 * \project WonderTrader
 * 
 * \brief ModuleHelper工具类测试套件
 * 
 * \details 测试ModuleHelper类的各种功能，包括：
 *          - 模块路径获取
 *          - 跨平台兼容性
 *          - 路径标准化
 *          - 目录管理
 */

#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include "ModuleHelper.hpp"
#include <string>
#include <thread>
#include <vector>
#include <atomic>
#include <chrono>

/*!
 * \brief ModuleHelper工具类测试套件
 * 
 * \details 测试ModuleHelper类的基本功能，包括：
 *          - 模块目录路径获取
 *          - 路径标准化处理
 *          - 跨平台兼容性
 *          - 静态方法调用
 */
class ModuleHelperTest : public ::testing::Test {
protected:
    void SetUp() override {
        // 测试前准备
    }
    
    void TearDown() override {
        // 测试后清理
    }
};

// ========== 路径获取测试 ==========

/*!
 * \brief 测试获取模块目录路径
 */
TEST_F(ModuleHelperTest, TestGetBinDir) {
    // 获取模块目录
    const char* bin_dir = getBinDir();
    
    // 验证返回值不为空
    ASSERT_NE(bin_dir, nullptr);
    EXPECT_GT(strlen(bin_dir), 0);
    
    // 验证路径格式（应该以斜杠结尾）
    std::string dir_path(bin_dir);
    EXPECT_TRUE(dir_path.back() == '/');
    
    // 验证路径是绝对路径或相对路径
    EXPECT_FALSE(dir_path.empty());
}

/*!
 * \brief 测试多次调用getBinDir的一致性
 */
TEST_F(ModuleHelperTest, TestGetBinDirConsistency) {
    // 多次调用应该返回相同的结果
    const char* dir1 = getBinDir();
    const char* dir2 = getBinDir();
    const char* dir3 = getBinDir();
    
    ASSERT_NE(dir1, nullptr);
    ASSERT_NE(dir2, nullptr);
    ASSERT_NE(dir3, nullptr);
    
    // 验证返回的字符串内容相同
    EXPECT_STREQ(dir1, dir2);
    EXPECT_STREQ(dir2, dir3);
    EXPECT_STREQ(dir1, dir3);
}

/*!
 * \brief 测试路径格式标准化
 */
TEST_F(ModuleHelperTest, TestPathStandardization) {
    const char* bin_dir = getBinDir();
    std::string dir_path(bin_dir);
    
    // 验证路径使用正斜杠分隔符
    EXPECT_EQ(dir_path.find('\\'), std::string::npos);
    
    // 验证路径以斜杠结尾
    EXPECT_TRUE(dir_path.back() == '/');
    
    // 验证路径不包含双斜杠（除了可能的协议部分）
    size_t double_slash_pos = dir_path.find("//");
    if (double_slash_pos != std::string::npos) {
        // 如果找到双斜杠，应该是在开头（如 file://）
        EXPECT_LT(double_slash_pos, 10);
    }
}

// ========== 路径有效性测试 ==========

/*!
 * \brief 测试返回路径的有效性
 */
TEST_F(ModuleHelperTest, TestPathValidity) {
    const char* bin_dir = getBinDir();
    std::string dir_path(bin_dir);
    
    // 移除末尾的斜杠进行目录存在性检查
    if (!dir_path.empty() && dir_path.back() == '/') {
        dir_path.pop_back();
    }
    
    // 验证路径格式合理（不包含非法字符）
    EXPECT_EQ(dir_path.find('\0'), std::string::npos);
    
    // 验证路径长度合理
    EXPECT_GT(dir_path.length(), 0);
    EXPECT_LT(dir_path.length(), 4096); // 合理的路径长度上限
}

/*!
 * \brief 测试路径字符编码
 */
TEST_F(ModuleHelperTest, TestPathEncoding) {
    const char* bin_dir = getBinDir();
    std::string dir_path(bin_dir);
    
    // 验证路径是有效的UTF-8字符串（基本ASCII检查）
    for (char c : dir_path) {
        // 检查是否为可打印字符或路径分隔符
        EXPECT_TRUE(std::isprint(static_cast<unsigned char>(c)) || c == '/' || c == '\\');
    }
}

// ========== 性能测试 ==========

/*!
 * \brief 测试getBinDir的性能
 */
TEST_F(ModuleHelperTest, TestGetBinDirPerformance) {
    const int num_calls = 1000;
    
    auto start = std::chrono::high_resolution_clock::now();
    
    // 多次调用getBinDir
    for (int i = 0; i < num_calls; ++i) {
        const char* dir = getBinDir();
        ASSERT_NE(dir, nullptr); // 确保每次调用都成功
    }
    
    auto end = std::chrono::high_resolution_clock::now();
    auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
    
    // 验证性能合理（1000次调用应该在合理时间内完成）
    EXPECT_LT(duration.count(), 100000); // 小于100毫秒
    
    // 平均每次调用时间应该很短
    double avg_time = static_cast<double>(duration.count()) / num_calls;
    EXPECT_LT(avg_time, 100.0); // 平均每次调用小于100微秒
}

// ========== 线程安全测试 ==========

/*!
 * \brief 测试多线程环境下的getBinDir调用
 */
TEST_F(ModuleHelperTest, TestGetBinDirThreadSafety) {
    const int num_threads = 10;
    const int calls_per_thread = 100;
    std::vector<std::thread> threads;
    std::vector<std::string> results(num_threads);
    std::atomic<int> success_count(0);
    
    // 创建多个线程同时调用getBinDir
    for (int i = 0; i < num_threads; ++i) {
        threads.emplace_back([&, i]() {
            bool all_consistent = true;
            std::string first_result;
            
            for (int j = 0; j < calls_per_thread; ++j) {
                const char* dir = getBinDir();
                if (dir != nullptr) {
                    std::string current_result(dir);
                    if (j == 0) {
                        first_result = current_result;
                    } else if (current_result != first_result) {
                        all_consistent = false;
                        break;
                    }
                } else {
                    all_consistent = false;
                    break;
                }
            }
            
            if (all_consistent && !first_result.empty()) {
                results[i] = first_result;
                success_count++;
            }
        });
    }
    
    // 等待所有线程完成
    for (auto& thread : threads) {
        thread.join();
    }
    
    // 验证所有线程都成功
    EXPECT_EQ(success_count.load(), num_threads);
    
    // 验证所有线程得到相同的结果
    if (success_count.load() > 0) {
        std::string expected_result = results[0];
        for (int i = 1; i < num_threads; ++i) {
            if (!results[i].empty()) {
                EXPECT_EQ(results[i], expected_result);
            }
        }
    }
}

// ========== 边界条件测试 ==========

/*!
 * \brief 测试连续大量调用
 */
TEST_F(ModuleHelperTest, TestMassiveCalls) {
    const int num_calls = 10000;
    std::string first_result;
    
    for (int i = 0; i < num_calls; ++i) {
        const char* dir = getBinDir();
        ASSERT_NE(dir, nullptr);
        
        std::string current_result(dir);
        if (i == 0) {
            first_result = current_result;
        } else {
            // 验证每次调用结果一致
            EXPECT_EQ(current_result, first_result);
        }
        
        // 验证基本格式
        EXPECT_FALSE(current_result.empty());
        EXPECT_TRUE(current_result.back() == '/');
    }
}

/*!
 * \brief 测试内存使用情况
 */
TEST_F(ModuleHelperTest, TestMemoryUsage) {
    // 获取初始结果
    const char* initial_dir = getBinDir();
    ASSERT_NE(initial_dir, nullptr);
    std::string initial_result(initial_dir);
    
    // 大量调用后验证结果仍然一致
    const int num_calls = 5000;
    for (int i = 0; i < num_calls; ++i) {
        const char* dir = getBinDir();
        ASSERT_NE(dir, nullptr);
        EXPECT_EQ(std::string(dir), initial_result);
    }
    
    // 最终验证
    const char* final_dir = getBinDir();
    ASSERT_NE(final_dir, nullptr);
    EXPECT_EQ(std::string(final_dir), initial_result);
}

// ========== 平台特定测试 ==========

/*!
 * \brief 测试路径分隔符处理
 */
TEST_F(ModuleHelperTest, TestPathSeparatorHandling) {
    const char* bin_dir = getBinDir();
    std::string dir_path(bin_dir);
    
    // 验证使用正确的路径分隔符
    EXPECT_EQ(dir_path.find('\\'), std::string::npos); // 不应包含反斜杠
    
    // 验证包含正斜杠（除非是根目录）
    if (dir_path.length() > 1) {
        EXPECT_NE(dir_path.find('/'), std::string::npos);
    }
    
    // 验证末尾分隔符
    EXPECT_TRUE(dir_path.back() == '/');
}

/*!
 * \brief 测试路径长度合理性
 */
TEST_F(ModuleHelperTest, TestPathLength) {
    const char* bin_dir = getBinDir();
    std::string dir_path(bin_dir);
    
    // 验证路径长度在合理范围内
    EXPECT_GT(dir_path.length(), 0);      // 不能为空
    EXPECT_LT(dir_path.length(), 1024);   // 不能过长
    
    // 验证不是只有分隔符
    EXPECT_GT(dir_path.length(), 1);
}

// ========== 功能完整性测试 ==========

/*!
 * \brief 测试返回值的完整性
 */
TEST_F(ModuleHelperTest, TestReturnValueCompleteness) {
    const char* bin_dir = getBinDir();
    
    // 验证返回值不为空指针
    ASSERT_NE(bin_dir, nullptr);
    
    // 验证返回值指向有效字符串
    EXPECT_GT(strlen(bin_dir), 0);
    
    // 验证字符串以null结尾
    std::string dir_path(bin_dir);
    EXPECT_EQ(dir_path.length(), strlen(bin_dir));
    
    // 验证路径格式正确
    EXPECT_TRUE(dir_path.back() == '/');
} 